<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>Map和Set</title>
    <!-- ES6引入新的数据类型Map和Set -->
    <!-- Map是一组键值对的结构,具有极快的查找速度 -->
</head>
<body>
<script type="text/javascript">

    let oneMap = new Map();
    let oneSet = new Set();
    console.log("创建map和set成功");
    // 举例,如果我们想要知道小明的成绩是多少,我们就需要使用两个Array;一个用于存储姓名,一个用于存储对应的成绩;
    var nameArray = ['li', 'zhou', 'yang'];
    var scroeArray = [90, 98, 87];
    // 如果人越多,Array越长,那么就要耗费更多的时间;但是使用Map,只要一个名称-成绩的对照表,直接根据名字查找,
    // 无论这个表有多慢,查找都很快速.
    // 初始化一个Map,需要一个二维数组
    // var exampleMap = new Map([
    //     ['li', 90],
    //     ['zhou', 98],
    //     ['yang', 87]
    // ]);
    console.log(oneMap.get('yang')); // 结果是87
    //我们也可以直接创建一个空Map,然后调用set方法进行添加元素
    oneMap.set('li', 90);
    oneMap.set('zhou', 98);
    oneMap.set('yang', 87);
    console.log(oneMap.get('yang')); // 结果是87
    // has方法可以用来检测Map是否包含某个key对应的元素
    var isHasLi = oneMap.has('li');
    console.log(isHasLi); // 结果是true
    var hasDelete = oneMap.delete('li');
    console.log("删除" + hasDelete); // 结果是 删除true
    // 另外,因为一个key只能对应一个value,所以多次对一个key放入value,后面的值会覆盖前面的值
    oneMap.set('niu', 89);
    oneMap.set('niu', 99);
    console.log(oneMap.get('niu')); // 结果是99

    // 下面来看set集合
    // Set和Map类似,也是一组key的结合,但是不存储value,由于key不重复,所以Set中没有重复的plus.key
    // 初始化set需要传入一个一维数组
    var mySet = new Set([1, 2, 3]);
    // 或使用add方法进行添加
    var secondSet = new Set();
    secondSet.add('li');
    secondSet.add('niu');
    // 注意添加相同的元素会自动去重
    secondSet.add('li');
    console.log(secondSet.size) //长度还是2
    // delete(key)可以删除元素
    secondSet.delete('li');
    console.log(secondSet.size);





    // // 迭代器 iterable,可以用于Map Set和Array
    // // 具有iterabl类型的集合,可以通过新的for....of循环遍历,并且遍历得到的是value,而不是key
    // for (var x of oneMap) {
    //     // console.log(x.toString());
    //     // zhou,98
    //     // yang,87
    //     // niu,99
    // }
    // // 对于map集合,我们可以获取key以及对应的value
    // for (var x of oneMap) {
    //     console.log(x[0] + " " + x[1]);
    //     // zhou 98
    //     // yang 87
    //     // niu 99
    // }
    // // 对于set集合
    // for (var x of secondSet) {
    //     // console.log(x); // 结果是niu
    // }


    // 下面来看下for..in和for...of的区别
    // for..in实际上遍历的是对象的属性名称,对于数组Array来说,实际上也是对象,她的每个元素的索引都被视为属性
    // ;当我们手动给数组对象添加额外的属性时候,使用for..in就会带来意外的效果


    // myArray.name = 'heihei';
    // myArray.age = 'heihei';
    // for (var x in myArray) {
    //     // console.log(x);
    //     // 结果是 0 1 2 name,这里把name也给遍历出来了;
    // }
    // // 但是使用for..of就不会出现这样的问题,他只循环集合本身的元素
    // for (var x of myArray) {
    //     console.log(x);
    //     // 结果是 1 3 5
    // }


    var secondSet = new Set();
    secondSet.add('li');
    secondSet.add('niu');

    var oneMap = new Map([
        ['li', 90],
        ['zhou', 98],
        ['yang', 87]
    ]);
    var myArray = [111, 222, 333,444];

    // forEach方法是iterable内置的方法,接收一个函数,每次迭代就自动回调该函数
    // oneMap.forEach(function(element, index, array) {
    //     // element: 指向当前元素的值
    //     // index: 指向当前索引
    //     // array: 指向Array对象本身
    //     console.log(element + ', index = ' + index+"---对象本身是:"+array);
    // });
    // 对Map集合来说,第一个参数value,第二个参数是key;
    // oneMap.forEach(function(value,key,map){
    //     console.log(value + ', key = ' + key+'--'+map);
    // });


    // 对于set集合来说,因为没有索引,所以第一个第二个参数都是value
    // secondSet.forEach(function(value,sameValue,set){
    //     console.log(value + ', sameValue = ' + sameValue+'--'+set);
    // });
    // 另外,js函数调用不要求参数一致,所以如果我们只关心value,可以这么写
    myArray.forEach(function(element){
        console.log(element);
        //结果是 111 222 333 444
    })
</script>
</body>
</html>
